// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include <vtkObjectFactory.h>
#include <vtkProperty2D.h>
#include "vtkAxesActor2D.h"

vtkStandardNewMacro(vtkAxesActor2D);


// **********************************************************************
// Instantiate this object.
//
//  Modifications:
//
// **********************************************************************

vtkAxesActor2D::vtkAxesActor2D()
{
  this->XAxis = vtkVisItAxisActor2D::New();
  this->XAxis->SetTickVisibility(1);
  this->XAxis->SetLabelVisibility(1);
  this->XAxis->SetTitleVisibility(1);
  this->XAxis->SetFontFamilyToCourier();
  this->XAxis->SetLabelFontHeight(0.02);
  this->XAxis->SetTitleFontHeight(0.02);
  this->XAxis->SetShadow(0);
  this->XAxis->SetAdjustLabels(1);
  this->XAxis->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedViewport();
  this->XAxis->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedViewport();
  this->XAxis->PickableOff();
  this->XAxis->SetUseSeparateColors(1);
  this->XAxis->SetGridlineXLength(0);
  this->XAxis->SetUseOrientationAngle(1);
  this->XAxis->SetOrientationAngle(0.);

  this->YAxis = vtkVisItAxisActor2D::New();
  this->YAxis->SetTickVisibility(1);
  this->YAxis->SetLabelVisibility(1);
  this->YAxis->SetTitleVisibility(1);
  this->YAxis->SetFontFamilyToCourier();
  this->YAxis->SetLabelFontHeight(0.02);
  this->YAxis->SetTitleFontHeight(0.02);
  this->YAxis->SetShadow(0);
  this->YAxis->SetAdjustLabels(1);
  this->YAxis->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedViewport();
  this->YAxis->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedViewport();
  this->YAxis->PickableOff();
  this->YAxis->SetUseSeparateColors(1);
  this->YAxis->SetGridlineYLength(0);
  this->YAxis->SetUseOrientationAngle(1);
  this->YAxis->SetOrientationAngle(-1.5707963);
}

vtkAxesActor2D::~vtkAxesActor2D()
{
  if (this->XAxis)
    {
    this->XAxis->Delete();
    this->XAxis = NULL;
    }
  
  if (this->YAxis)
    {
    this->YAxis->Delete();
    this->YAxis = NULL;
    }
}


void 
vtkAxesActor2D::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "XAxis: \n";
  this->XAxis->PrintSelf(os, indent.GetNextIndent());
  os << indent << "YAxis: \n";
  this->YAxis->PrintSelf(os, indent.GetNextIndent());
}


// ****************************************************************************
// Render the axis, ticks, title, and labels.
// ****************************************************************************

int 
vtkAxesActor2D::RenderOverlay(vtkViewport *viewport)
{
  int renderedSomething=0;

  renderedSomething += this->XAxis->RenderOverlay(viewport);
  renderedSomething += this->YAxis->RenderOverlay(viewport);

  return renderedSomething;
}


// ****************************************************************************
// Render the axis, ticks, title, and labels.
// ****************************************************************************

int 
vtkAxesActor2D::RenderOpaqueGeometry(vtkViewport *viewport)
{
  int renderedSomething=0;

  if (this->XAxis->GetDrawGridlines() || this->YAxis->GetDrawGridlines())
    {
    int *x = this->XAxis->GetPoint2Coordinate()->GetComputedViewportValue(viewport);
    int *y = this->YAxis->GetPoint1Coordinate()->GetComputedViewportValue(viewport);
    this->XAxis->SetGridlineYLength(abs(x[1] - y[1]));
    this->YAxis->SetGridlineXLength(abs(x[0] - y[0]));
    }
  renderedSomething += this->XAxis->RenderOpaqueGeometry(viewport);
  renderedSomething += this->YAxis->RenderOpaqueGeometry(viewport);

  return renderedSomething;
}


// ****************************************************************************
// Release any graphics resources that are being consumed by this actor.
// The parameter window could be used to determine which graphic
// resources to release.
// ****************************************************************************

void 
vtkAxesActor2D::ReleaseGraphicsResources(vtkWindow *win)
{
  this->XAxis->ReleaseGraphicsResources(win);
  this->YAxis->ReleaseGraphicsResources(win);
}


// ****************************************************************************
// Set the viewport. The viewport controls the coordinate values.
// ****************************************************************************

void 
vtkAxesActor2D::SetCoordinateValuesFromViewport(double vl, double vb, 
                                                double vr, double vt)
{
  this->XAxis->GetPoint1Coordinate()->SetValue(vl, vb);
  this->XAxis->GetPoint2Coordinate()->SetValue(vr, vb);

  //
  // Make coordinates for y-axis backwards so the labels will appear on
  // the left side and out of the viewport.
  //
  this->YAxis->GetPoint1Coordinate()->SetValue(vl, vt);
  this->YAxis->GetPoint2Coordinate()->SetValue(vl, vb);
}


// ****************************************************************************
// Sets the line width
// ****************************************************************************

void 
vtkAxesActor2D::SetLineWidth(int width)
{
  this->XAxis->GetProperty()->SetLineWidth(width);
  this->YAxis->GetProperty()->SetLineWidth(width);
}


// ****************************************************************************
// Set the color for the axes
// ****************************************************************************

void 
vtkAxesActor2D::SetColor(double r, double g, double b)
{
  this->XAxis->GetProperty()->SetColor(r, g, b);
  this->YAxis->GetProperty()->SetColor(r, g, b);
}


// ****************************************************************************
// Set the log scaling
// ****************************************************************************

void 
vtkAxesActor2D::SetXLogScaling(bool logScale)
{
  this->XAxis->SetLogScale(logScale);
}

void 
vtkAxesActor2D::SetYLogScaling(bool logScale)
{
  this->YAxis->SetLogScale(logScale);
}

// ****************************************************************************
// LABEL CONTROLS
// ****************************************************************************

// ****************************************************************************
// Set the label range of the axes.
// ****************************************************************************

void 
vtkAxesActor2D::SetXRange(double minX, double maxX)
{
  this->XAxis->SetRange(minX, maxX);
}

void
vtkAxesActor2D::SetYRange(double minY, double maxY)
{
  //
  // We put the y-axis in reverse so that its labels would appear on the
  // correct side of the viewport.  Must propogate kludge by sending
  // range in backwards.
  //
  this->YAxis->SetRange(maxY, minY);
}


// ****************************************************************************
// Set the visibility of labels
// ****************************************************************************

void 
vtkAxesActor2D::SetXLabelVisibility(bool vis)
{
  this->XAxis->SetLabelVisibility(vis);
}

void 
vtkAxesActor2D::SetYLabelVisibility(bool vis)
{
  this->YAxis->SetLabelVisibility(vis);
}


// ****************************************************************************
// Set the major tick label scale
// ****************************************************************************

void 
vtkAxesActor2D::SetXLabelScale(double labelScale)
{
  this->XAxis->SetMajorTickLabelScale(labelScale);
}

void 
vtkAxesActor2D::SetYLabelScale(double labelScale)
{
  this->YAxis->SetMajorTickLabelScale(labelScale);
}


// ****************************************************************************
// Set the label format string
// ****************************************************************************

void 
vtkAxesActor2D::SetXLabelFormatString(char *format)
{
  this->XAxis->SetLabelFormat(format);
}

void 
vtkAxesActor2D::SetYLabelFormatString(char *format)
{
  this->YAxis->SetLabelFormat(format);
}


// ****************************************************************************
// Set the label format string for log scaling
// ****************************************************************************

void 
vtkAxesActor2D::SetXLogLabelFormatString(char *format)
{
  this->XAxis->SetLogLabelFormat(format);
}

void 
vtkAxesActor2D::SetYLogLabelFormatString(char *format)
{
  this->YAxis->SetLogLabelFormat(format);
}


// ****************************************************************************
// Set the label font height
// ****************************************************************************

void 
vtkAxesActor2D::SetXLabelFontHeight(double height)
{
  this->XAxis->SetLabelFontHeight(height);
}

void 
vtkAxesActor2D::SetYLabelFontHeight(double height)
{
  this->YAxis->SetLabelFontHeight(height);
}


// ****************************************************************************
// Set the flag specifying if labels are auto adjusted
// ****************************************************************************

void 
vtkAxesActor2D::SetAutoAdjustLabels(bool autoAdjust)
{
  this->XAxis->SetAdjustLabels(autoAdjust);
  this->YAxis->SetAdjustLabels(autoAdjust);
}


// ****************************************************************************
// Retrieve the text property for labels
// ****************************************************************************

vtkTextProperty *
vtkAxesActor2D::GetXLabelTextProperty()
{
  return this->XAxis->GetLabelTextProperty();
}

vtkTextProperty *
vtkAxesActor2D::GetYLabelTextProperty()
{
  return this->YAxis->GetLabelTextProperty();
}


// ****************************************************************************
// TITLE CONTROLS
// ****************************************************************************


// ****************************************************************************
// Set the title 
// ****************************************************************************

void 
vtkAxesActor2D::SetXTitle(char *title)
{
  this->XAxis->SetTitle(title);
}

void 
vtkAxesActor2D::SetYTitle(char *title)
{
  this->YAxis->SetTitle(title);
}


// ****************************************************************************
// Set the title font height
// ****************************************************************************

void 
vtkAxesActor2D::SetXTitleFontHeight(double height)
{
  this->XAxis->SetTitleFontHeight(height);
}

void 
vtkAxesActor2D::SetYTitleFontHeight(double height)
{
  this->YAxis->SetTitleFontHeight(height);
}


// ****************************************************************************
// Set the visibility of title
// ****************************************************************************

void 
vtkAxesActor2D::SetXTitleVisibility(bool vis)
{
  this->XAxis->SetTitleVisibility(vis);
}

void 
vtkAxesActor2D::SetYTitleVisibility(bool vis)
{
  this->YAxis->SetTitleVisibility(vis);
}


// ****************************************************************************
// Retrieve the text property for titles
// ****************************************************************************

vtkTextProperty *
vtkAxesActor2D::GetXTitleTextProperty()
{
  return this->XAxis->GetTitleTextProperty();
}

vtkTextProperty *
vtkAxesActor2D::GetYTitleTextProperty()
{
  return this->YAxis->GetTitleTextProperty();
}


// ****************************************************************************
// TICK CONTROLS
// ****************************************************************************


// ****************************************************************************
// Set the location for the tick marks.
// ****************************************************************************

void 
vtkAxesActor2D::SetTickLocation(int loc)
{
  this->XAxis->SetTickLocation(loc);
  this->YAxis->SetTickLocation(loc);
}


// ****************************************************************************
// Set the visibility of ticks.
// ****************************************************************************

void 
vtkAxesActor2D::SetXMinorTickVisibility(bool vis)
{
  this->XAxis->SetMinorTicksVisible(vis);
}

void 
vtkAxesActor2D::SetXMajorTickVisibility(bool vis)
{
  this->XAxis->SetTickVisibility(vis);
}

void 
vtkAxesActor2D::SetYMinorTickVisibility(bool vis)
{
  this->YAxis->SetMinorTicksVisible(vis);
}

void 
vtkAxesActor2D::SetYMajorTickVisibility(bool vis)
{
  this->YAxis->SetTickVisibility(vis);
}


// ****************************************************************************
// Sets the minimum value for Major Ticks
// ****************************************************************************

void 
vtkAxesActor2D::SetXMajorTickMinimum(double minV)
{
  this->XAxis->SetMajorTickMinimum(minV);
}

void 
vtkAxesActor2D::SetYMajorTickMinimum(double minV)
{
  this->YAxis->SetMajorTickMinimum(minV);
}


// ****************************************************************************
// Sets the maximum value for Major Ticks
// ****************************************************************************

void 
vtkAxesActor2D::SetXMajorTickMaximum(double maxV)
{
  this->XAxis->SetMajorTickMaximum(maxV);
}

void 
vtkAxesActor2D::SetYMajorTickMaximum(double maxV)
{
  this->YAxis->SetMajorTickMaximum(maxV);
}


// ****************************************************************************
// Sets the spacing for Major Ticks
// ****************************************************************************

void 
vtkAxesActor2D::SetXMajorTickSpacing(double spacing)
{
  this->XAxis->SetMajorTickSpacing(spacing);
}

void 
vtkAxesActor2D::SetYMajorTickSpacing(double spacing)
{
  this->YAxis->SetMajorTickSpacing(spacing);
}


// ****************************************************************************
// Sets the spacing for Minor Ticks
// ****************************************************************************

void 
vtkAxesActor2D::SetXMinorTickSpacing(double spacing)
{
  this->XAxis->SetMinorTickSpacing(spacing);
}

void 
vtkAxesActor2D::SetYMinorTickSpacing(double spacing)
{
  this->YAxis->SetMinorTickSpacing(spacing);
}


// ****************************************************************************
// GRID CONTROLS
// ****************************************************************************


// ****************************************************************************
// Set the visibility of gridlines
// ****************************************************************************

void 
vtkAxesActor2D::SetXGridVisibility(bool vis)
{
  this->XAxis->SetDrawGridlines(vis);
}

void 
vtkAxesActor2D::SetYGridVisibility(bool vis)
{
  this->YAxis->SetDrawGridlines(vis);
}


// ****************************************************************************
// Take into account the MTimes of the different axes
//
// ****************************************************************************

vtkMTimeType
vtkAxesActor2D::GetMTime()
{
  vtkMTimeType mTime = this->Superclass::GetMTime();

  vtkMTimeType time;
  time = this->XAxis->GetMTime();
  mTime = (time > mTime ? time : mTime);
  time = this->YAxis->GetMTime();
  mTime = (time > mTime ? time : mTime);

  return mTime;
}
